{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How to do retrieval\n",
    "\n",
    ":::info Prerequisites\n",
    "\n",
    "This guide assumes familiarity with the following:\n",
    "\n",
    "- [Chatbots](/docs/tutorials/chatbot)\n",
    "- [Retrieval-augmented generation](/docs/tutorials/rag)\n",
    "\n",
    ":::\n",
    "\n",
    "Retrieval is a common technique chatbots use to augment their responses with data outside a chat model’s training data. This section will cover how to implement retrieval in the context of chatbots, but it’s worth noting that retrieval is a very subtle and deep topic.\n",
    "\n",
    "## Setup\n",
    "\n",
    "You’ll need to install a few packages, and set any LLM API keys:\n",
    "\n",
    "```{=mdx}\n",
    "import Npm2Yarn from \"@theme/Npm2Yarn\";\n",
    "\n",
    "<Npm2Yarn>\n",
    "  @langchain/openai cheerio\n",
    "</Npm2Yarn>\n",
    "```\n",
    "\n",
    "Let’s also set up a chat model that we’ll use for the below examples.\n",
    "\n",
    "```{=mdx}\n",
    "import ChatModelTabs from \"@theme/ChatModelTabs\";\n",
    "\n",
    "<ChatModelTabs customVarName=\"llm\" />\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Creating a retriever\n",
    "\n",
    "We’ll use [the LangSmith documentation](https://docs.smith.langchain.com) as source material and store the content in a vectorstore for later retrieval. Note that this example will gloss over some of the specifics around parsing and storing a data source - you can see more [in-depth documentation on creating retrieval systems here](/docs/how_to/#qa-with-rag).\n",
    "\n",
    "Let’s use a document loader to pull text from the docs:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[33m36687\u001b[39m"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import \"cheerio\";\n",
    "import { CheerioWebBaseLoader } from \"langchain/document_loaders/web/cheerio\";\n",
    "\n",
    "const loader = new CheerioWebBaseLoader(\n",
    "  \"https://docs.smith.langchain.com/user_guide\"\n",
    ");\n",
    "\n",
    "const rawDocs = await loader.load();\n",
    "\n",
    "rawDocs[0].pageContent.length;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we split it into smaller chunks that the LLM’s context window can handle and store it in a vector database:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import { RecursiveCharacterTextSplitter } from \"langchain/text_splitter\";\n",
    "\n",
    "const textSplitter = new RecursiveCharacterTextSplitter({\n",
    "  chunkSize: 500,\n",
    "  chunkOverlap: 0,\n",
    "});\n",
    "\n",
    "const allSplits = await textSplitter.splitDocuments(rawDocs);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then we embed and store those chunks in a vector database:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import { OpenAIEmbeddings } from \"@langchain/openai\";\n",
    "import { MemoryVectorStore } from \"langchain/vectorstores/memory\";\n",
    "\n",
    "const vectorstore = await MemoryVectorStore.fromDocuments(\n",
    "  allSplits,\n",
    "  new OpenAIEmbeddings()\n",
    ");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And finally, let’s create a retriever from our initialized vectorstore:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\n",
      "  Document {\n",
      "    pageContent: \"These test cases can be uploaded in bulk, created on the fly, or exported from application traces. L\"... 294 more characters,\n",
      "    metadata: {\n",
      "      source: \"https://docs.smith.langchain.com/user_guide\",\n",
      "      loc: { lines: { from: 7, to: 7 } }\n",
      "    }\n",
      "  },\n",
      "  Document {\n",
      "    pageContent: \"We provide native rendering of chat messages, functions, and retrieve documents.Initial Test Set​Whi\"... 347 more characters,\n",
      "    metadata: {\n",
      "      source: \"https://docs.smith.langchain.com/user_guide\",\n",
      "      loc: { lines: { from: 6, to: 6 } }\n",
      "    }\n",
      "  },\n",
      "  Document {\n",
      "    pageContent: \"will help in curation of test cases that can help track regressions/improvements and development of \"... 393 more characters,\n",
      "    metadata: {\n",
      "      source: \"https://docs.smith.langchain.com/user_guide\",\n",
      "      loc: { lines: { from: 11, to: 11 } }\n",
      "    }\n",
      "  },\n",
      "  Document {\n",
      "    pageContent: \"that time period — this is especially handy for debugging production issues.LangSmith also allows fo\"... 396 more characters,\n",
      "    metadata: {\n",
      "      source: \"https://docs.smith.langchain.com/user_guide\",\n",
      "      loc: { lines: { from: 11, to: 11 } }\n",
      "    }\n",
      "  }\n",
      "]\n"
     ]
    }
   ],
   "source": [
    "const retriever = vectorstore.asRetriever(4);\n",
    "\n",
    "const docs = await retriever.invoke(\"how can langsmith help with testing?\");\n",
    "\n",
    "console.log(docs);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see that invoking the retriever above results in some parts of the LangSmith docs that contain information about testing that our chatbot can use as context when answering questions. And now we’ve got a retriever that can return related data from the LangSmith docs!\n",
    "\n",
    "## Document chains\n",
    "\n",
    "Now that we have a retriever that can return LangChain docs, let’s create a chain that can use them as context to answer questions. We’ll use a `createStuffDocumentsChain` helper function to \"stuff\" all of the input documents into the prompt. It will also handle formatting the docs as strings.\n",
    "\n",
    "In addition to a chat model, the function also expects a prompt that has a `context` variable, as well as a placeholder for chat history messages named `messages`. We’ll create an appropriate prompt and pass it as shown below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import { createStuffDocumentsChain } from \"langchain/chains/combine_documents\";\n",
    "import {\n",
    "  ChatPromptTemplate,\n",
    "  MessagesPlaceholder,\n",
    "} from \"@langchain/core/prompts\";\n",
    "\n",
    "const SYSTEM_TEMPLATE = `Answer the user's questions based on the below context. \n",
    "If the context doesn't contain any relevant information to the question, don't make something up and just say \"I don't know\":\n",
    "\n",
    "<context>\n",
    "{context}\n",
    "</context>\n",
    "`;\n",
    "\n",
    "const questionAnsweringPrompt = ChatPromptTemplate.fromMessages([\n",
    "  [\"system\", SYSTEM_TEMPLATE],\n",
    "  new MessagesPlaceholder(\"messages\"),\n",
    "]);\n",
    "\n",
    "const documentChain = await createStuffDocumentsChain({\n",
    "  llm,\n",
    "  prompt: questionAnsweringPrompt,\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can invoke this `documentChain` by itself to answer questions. Let’s use the docs we retrieved above and the same question, `how can langsmith help with testing?`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[32m\"Yes, LangSmith can help test your LLM applications. It allows developers to create datasets, which a\"\u001b[39m... 229 more characters"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import { HumanMessage, AIMessage } from \"@langchain/core/messages\";\n",
    "\n",
    "await documentChain.invoke({\n",
    "  messages: [new HumanMessage(\"Can LangSmith help test my LLM applications?\")],\n",
    "  context: docs,\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Looks good! For comparison, we can try it with no context docs and compare the result:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\u001b[32m\"I don't know.\"\u001b[39m"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "await documentChain.invoke({\n",
    "  messages: [new HumanMessage(\"Can LangSmith help test my LLM applications?\")],\n",
    "  context: [],\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see that the LLM does not return any results.\n",
    "\n",
    "## Retrieval chains\n",
    "\n",
    "Let’s combine this document chain with the retriever. Here’s one way this can look:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "import type { BaseMessage } from \"@langchain/core/messages\";\n",
    "import {\n",
    "  RunnablePassthrough,\n",
    "  RunnableSequence,\n",
    "} from \"@langchain/core/runnables\";\n",
    "\n",
    "const parseRetrieverInput = (params: { messages: BaseMessage[] }) => {\n",
    "  return params.messages[params.messages.length - 1].content;\n",
    "};\n",
    "\n",
    "const retrievalChain = RunnablePassthrough.assign({\n",
    "  context: RunnableSequence.from([parseRetrieverInput, retriever]),\n",
    "}).assign({\n",
    "  answer: documentChain,\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Given a list of input messages, we extract the content of the last message in the list and pass that to the retriever to fetch some documents. Then, we pass those documents as context to our document chain to generate a final response.\n",
    "\n",
    "Invoking this chain combines both steps outlined above:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{\n",
       "  messages: [\n",
       "    HumanMessage {\n",
       "      lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "      lc_kwargs: {\n",
       "        content: \u001b[32m\"Can LangSmith help test my LLM applications?\"\u001b[39m,\n",
       "        additional_kwargs: {},\n",
       "        response_metadata: {}\n",
       "      },\n",
       "      lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "      content: \u001b[32m\"Can LangSmith help test my LLM applications?\"\u001b[39m,\n",
       "      name: \u001b[90mundefined\u001b[39m,\n",
       "      additional_kwargs: {},\n",
       "      response_metadata: {}\n",
       "    }\n",
       "  ],\n",
       "  context: [\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"These test cases can be uploaded in bulk, created on the fly, or exported from application traces. L\"\u001b[39m... 294 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    },\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"this guide, we’ll highlight the breadth of workflows LangSmith supports and how they fit into each s\"\u001b[39m... 343 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    },\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"We provide native rendering of chat messages, functions, and retrieve documents.Initial Test Set​Whi\"\u001b[39m... 347 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    },\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"The ability to rapidly understand how the model is performing — and debug where it is failing — is i\"\u001b[39m... 138 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    }\n",
       "  ],\n",
       "  answer: \u001b[32m\"Yes, LangSmith can help test your LLM applications. It allows developers to create datasets, which a\"\u001b[39m... 297 more characters\n",
       "}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "await retrievalChain.invoke({\n",
    "  messages: [new HumanMessage(\"Can LangSmith help test my LLM applications?\")],\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Looks good!\n",
    "\n",
    "## Query transformation\n",
    "\n",
    "Our retrieval chain is capable of answering questions about LangSmith, but there’s a problem - chatbots interact with users conversationally, and therefore have to deal with followup questions.\n",
    "\n",
    "The chain in its current form will struggle with this. Consider a followup question to our original question like `Tell me more!`. If we invoke our retriever with that query directly, we get documents irrelevant to LLM application testing:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[\n",
       "  Document {\n",
       "    pageContent: \u001b[32m\"Oftentimes, changes in the prompt, retrieval strategy, or model choice can have huge implications in\"\u001b[39m... 40 more characters,\n",
       "    metadata: {\n",
       "      source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "      loc: { lines: { from: \u001b[33m8\u001b[39m, to: \u001b[33m8\u001b[39m } }\n",
       "    }\n",
       "  },\n",
       "  Document {\n",
       "    pageContent: \u001b[32m\"This allows you to quickly test out different prompts and models. You can open the playground from a\"\u001b[39m... 37 more characters,\n",
       "    metadata: {\n",
       "      source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "      loc: { lines: { from: \u001b[33m10\u001b[39m, to: \u001b[33m10\u001b[39m } }\n",
       "    }\n",
       "  },\n",
       "  Document {\n",
       "    pageContent: \u001b[32m\"We provide native rendering of chat messages, functions, and retrieve documents.Initial Test Set​Whi\"\u001b[39m... 347 more characters,\n",
       "    metadata: {\n",
       "      source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "      loc: { lines: { from: \u001b[33m6\u001b[39m, to: \u001b[33m6\u001b[39m } }\n",
       "    }\n",
       "  },\n",
       "  Document {\n",
       "    pageContent: \u001b[32m\"together, making it easier to track the performance of and annotate your application across multiple\"\u001b[39m... 244 more characters,\n",
       "    metadata: {\n",
       "      source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "      loc: { lines: { from: \u001b[33m11\u001b[39m, to: \u001b[33m11\u001b[39m } }\n",
       "    }\n",
       "  }\n",
       "]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "await retriever.invoke(\"Tell me more!\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is because the retriever has no innate concept of state, and will only pull documents most similar to the query given. To solve this, we can transform the query into a standalone query without any external references an LLM.\n",
    "\n",
    "Here’s an example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage {\n",
       "  lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "  lc_kwargs: {\n",
       "    content: \u001b[32m'\"LangSmith LLM application testing and evaluation features\"'\u001b[39m,\n",
       "    tool_calls: [],\n",
       "    invalid_tool_calls: [],\n",
       "    additional_kwargs: { function_call: \u001b[90mundefined\u001b[39m, tool_calls: \u001b[90mundefined\u001b[39m },\n",
       "    response_metadata: {}\n",
       "  },\n",
       "  lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "  content: \u001b[32m'\"LangSmith LLM application testing and evaluation features\"'\u001b[39m,\n",
       "  name: \u001b[90mundefined\u001b[39m,\n",
       "  additional_kwargs: { function_call: \u001b[90mundefined\u001b[39m, tool_calls: \u001b[90mundefined\u001b[39m },\n",
       "  response_metadata: {\n",
       "    tokenUsage: { completionTokens: \u001b[33m11\u001b[39m, promptTokens: \u001b[33m144\u001b[39m, totalTokens: \u001b[33m155\u001b[39m },\n",
       "    finish_reason: \u001b[32m\"stop\"\u001b[39m\n",
       "  },\n",
       "  tool_calls: [],\n",
       "  invalid_tool_calls: []\n",
       "}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "const queryTransformPrompt = ChatPromptTemplate.fromMessages([\n",
    "  new MessagesPlaceholder(\"messages\"),\n",
    "  [\n",
    "    \"user\",\n",
    "    \"Given the above conversation, generate a search query to look up in order to get information relevant to the conversation. Only respond with the query, nothing else.\",\n",
    "  ],\n",
    "]);\n",
    "\n",
    "const queryTransformationChain = queryTransformPrompt.pipe(llm);\n",
    "\n",
    "await queryTransformationChain.invoke({\n",
    "  messages: [\n",
    "    new HumanMessage(\"Can LangSmith help test my LLM applications?\"),\n",
    "    new AIMessage(\n",
    "      \"Yes, LangSmith can help test and evaluate your LLM applications. It allows you to quickly edit examples and add them to datasets to expand the surface area of your evaluation sets or to fine-tune a model for improved quality or reduced costs. Additionally, LangSmith can be used to monitor your application, log all traces, visualize latency and token usage statistics, and troubleshoot specific issues as they arise.\"\n",
    "    ),\n",
    "    new HumanMessage(\"Tell me more!\"),\n",
    "  ],\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Awesome! That transformed query would pull up context documents related to LLM application testing.\n",
    "\n",
    "Let’s add this to our retrieval chain. We can wrap our retriever as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import { RunnableBranch } from \"@langchain/core/runnables\";\n",
    "import { StringOutputParser } from \"@langchain/core/output_parsers\";\n",
    "\n",
    "const queryTransformingRetrieverChain = RunnableBranch.from([\n",
    "  [\n",
    "    (params: { messages: BaseMessage[] }) => params.messages.length === 1,\n",
    "    RunnableSequence.from([parseRetrieverInput, retriever]),\n",
    "  ],\n",
    "  queryTransformPrompt\n",
    "    .pipe(llm)\n",
    "    .pipe(new StringOutputParser())\n",
    "    .pipe(retriever),\n",
    "]).withConfig({ runName: \"chat_retriever_chain\" });"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, we can use this query transformation chain to make our retrieval chain better able to handle such followup questions:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "const conversationalRetrievalChain = RunnablePassthrough.assign({\n",
    "  context: queryTransformingRetrieverChain,\n",
    "}).assign({\n",
    "  answer: documentChain,\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Awesome! Let’s invoke this new chain with the same inputs as earlier:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{\n",
       "  messages: [\n",
       "    HumanMessage {\n",
       "      lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "      lc_kwargs: {\n",
       "        content: \u001b[32m\"Can LangSmith help test my LLM applications?\"\u001b[39m,\n",
       "        additional_kwargs: {},\n",
       "        response_metadata: {}\n",
       "      },\n",
       "      lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "      content: \u001b[32m\"Can LangSmith help test my LLM applications?\"\u001b[39m,\n",
       "      name: \u001b[90mundefined\u001b[39m,\n",
       "      additional_kwargs: {},\n",
       "      response_metadata: {}\n",
       "    }\n",
       "  ],\n",
       "  context: [\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"These test cases can be uploaded in bulk, created on the fly, or exported from application traces. L\"\u001b[39m... 294 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    },\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"this guide, we’ll highlight the breadth of workflows LangSmith supports and how they fit into each s\"\u001b[39m... 343 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    },\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"We provide native rendering of chat messages, functions, and retrieve documents.Initial Test Set​Whi\"\u001b[39m... 347 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    },\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"The ability to rapidly understand how the model is performing — and debug where it is failing — is i\"\u001b[39m... 138 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    }\n",
       "  ],\n",
       "  answer: \u001b[32m\"Yes, LangSmith can help test your LLM applications. It allows developers to create datasets, which a\"\u001b[39m... 297 more characters\n",
       "}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "await conversationalRetrievalChain.invoke({\n",
    "  messages: [new HumanMessage(\"Can LangSmith help test my LLM applications?\")],\n",
    "});"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{\n",
       "  messages: [\n",
       "    HumanMessage {\n",
       "      lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "      lc_kwargs: {\n",
       "        content: \u001b[32m\"Can LangSmith help test my LLM applications?\"\u001b[39m,\n",
       "        additional_kwargs: {},\n",
       "        response_metadata: {}\n",
       "      },\n",
       "      lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "      content: \u001b[32m\"Can LangSmith help test my LLM applications?\"\u001b[39m,\n",
       "      name: \u001b[90mundefined\u001b[39m,\n",
       "      additional_kwargs: {},\n",
       "      response_metadata: {}\n",
       "    },\n",
       "    AIMessage {\n",
       "      lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "      lc_kwargs: {\n",
       "        content: \u001b[32m\"Yes, LangSmith can help test and evaluate your LLM applications. It allows you to quickly edit examp\"\u001b[39m... 317 more characters,\n",
       "        tool_calls: [],\n",
       "        invalid_tool_calls: [],\n",
       "        additional_kwargs: {},\n",
       "        response_metadata: {}\n",
       "      },\n",
       "      lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "      content: \u001b[32m\"Yes, LangSmith can help test and evaluate your LLM applications. It allows you to quickly edit examp\"\u001b[39m... 317 more characters,\n",
       "      name: \u001b[90mundefined\u001b[39m,\n",
       "      additional_kwargs: {},\n",
       "      response_metadata: {},\n",
       "      tool_calls: [],\n",
       "      invalid_tool_calls: []\n",
       "    },\n",
       "    HumanMessage {\n",
       "      lc_serializable: \u001b[33mtrue\u001b[39m,\n",
       "      lc_kwargs: {\n",
       "        content: \u001b[32m\"Tell me more!\"\u001b[39m,\n",
       "        additional_kwargs: {},\n",
       "        response_metadata: {}\n",
       "      },\n",
       "      lc_namespace: [ \u001b[32m\"langchain_core\"\u001b[39m, \u001b[32m\"messages\"\u001b[39m ],\n",
       "      content: \u001b[32m\"Tell me more!\"\u001b[39m,\n",
       "      name: \u001b[90mundefined\u001b[39m,\n",
       "      additional_kwargs: {},\n",
       "      response_metadata: {}\n",
       "    }\n",
       "  ],\n",
       "  context: [\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"These test cases can be uploaded in bulk, created on the fly, or exported from application traces. L\"\u001b[39m... 294 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    },\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"We provide native rendering of chat messages, functions, and retrieve documents.Initial Test Set​Whi\"\u001b[39m... 347 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    },\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"this guide, we’ll highlight the breadth of workflows LangSmith supports and how they fit into each s\"\u001b[39m... 343 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    },\n",
       "    Document {\n",
       "      pageContent: \u001b[32m\"will help in curation of test cases that can help track regressions/improvements and development of \"\u001b[39m... 393 more characters,\n",
       "      metadata: {\n",
       "        source: \u001b[32m\"https://docs.smith.langchain.com/user_guide\"\u001b[39m,\n",
       "        loc: { lines: \u001b[36m[Object]\u001b[39m }\n",
       "      }\n",
       "    }\n",
       "  ],\n",
       "  answer: \u001b[32m\"LangSmith supports a variety of workflows to aid in the development of your applications, from creat\"\u001b[39m... 607 more characters\n",
       "}"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "await conversationalRetrievalChain.invoke({\n",
    "  messages: [\n",
    "    new HumanMessage(\"Can LangSmith help test my LLM applications?\"),\n",
    "    new AIMessage(\n",
    "      \"Yes, LangSmith can help test and evaluate your LLM applications. It allows you to quickly edit examples and add them to datasets to expand the surface area of your evaluation sets or to fine-tune a model for improved quality or reduced costs. Additionally, LangSmith can be used to monitor your application, log all traces, visualize latency and token usage statistics, and troubleshoot specific issues as they arise.\"\n",
    "    ),\n",
    "    new HumanMessage(\"Tell me more!\"),\n",
    "  ],\n",
    "});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can check out [this LangSmith trace](https://smith.langchain.com/public/dc4d6bd4-fea5-45df-be94-06ad18882ae9/r) to see the internal query transformation step for yourself.\n",
    "\n",
    "## Streaming\n",
    "\n",
    "Because this chain is constructed with LCEL, you can use familiar methods like `.stream()` with it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  messages: [\n",
      "    HumanMessage {\n",
      "      lc_serializable: true,\n",
      "      lc_kwargs: {\n",
      "        content: \"Can LangSmith help test my LLM applications?\",\n",
      "        additional_kwargs: {},\n",
      "        response_metadata: {}\n",
      "      },\n",
      "      lc_namespace: [ \"langchain_core\", \"messages\" ],\n",
      "      content: \"Can LangSmith help test my LLM applications?\",\n",
      "      name: undefined,\n",
      "      additional_kwargs: {},\n",
      "      response_metadata: {}\n",
      "    },\n",
      "    AIMessage {\n",
      "      lc_serializable: true,\n",
      "      lc_kwargs: {\n",
      "        content: \"Yes, LangSmith can help test and evaluate your LLM applications. It allows you to quickly edit examp\"... 317 more characters,\n",
      "        tool_calls: [],\n",
      "        invalid_tool_calls: [],\n",
      "        additional_kwargs: {},\n",
      "        response_metadata: {}\n",
      "      },\n",
      "      lc_namespace: [ \"langchain_core\", \"messages\" ],\n",
      "      content: \"Yes, LangSmith can help test and evaluate your LLM applications. It allows you to quickly edit examp\"... 317 more characters,\n",
      "      name: undefined,\n",
      "      additional_kwargs: {},\n",
      "      response_metadata: {},\n",
      "      tool_calls: [],\n",
      "      invalid_tool_calls: []\n",
      "    },\n",
      "    HumanMessage {\n",
      "      lc_serializable: true,\n",
      "      lc_kwargs: {\n",
      "        content: \"Tell me more!\",\n",
      "        additional_kwargs: {},\n",
      "        response_metadata: {}\n",
      "      },\n",
      "      lc_namespace: [ \"langchain_core\", \"messages\" ],\n",
      "      content: \"Tell me more!\",\n",
      "      name: undefined,\n",
      "      additional_kwargs: {},\n",
      "      response_metadata: {}\n",
      "    }\n",
      "  ]\n",
      "}\n",
      "{\n",
      "  context: [\n",
      "    Document {\n",
      "      pageContent: \"These test cases can be uploaded in bulk, created on the fly, or exported from application traces. L\"... 294 more characters,\n",
      "      metadata: {\n",
      "        source: \"https://docs.smith.langchain.com/user_guide\",\n",
      "        loc: { lines: [Object] }\n",
      "      }\n",
      "    },\n",
      "    Document {\n",
      "      pageContent: \"We provide native rendering of chat messages, functions, and retrieve documents.Initial Test Set​Whi\"... 347 more characters,\n",
      "      metadata: {\n",
      "        source: \"https://docs.smith.langchain.com/user_guide\",\n",
      "        loc: { lines: [Object] }\n",
      "      }\n",
      "    },\n",
      "    Document {\n",
      "      pageContent: \"this guide, we’ll highlight the breadth of workflows LangSmith supports and how they fit into each s\"... 343 more characters,\n",
      "      metadata: {\n",
      "        source: \"https://docs.smith.langchain.com/user_guide\",\n",
      "        loc: { lines: [Object] }\n",
      "      }\n",
      "    },\n",
      "    Document {\n",
      "      pageContent: \"will help in curation of test cases that can help track regressions/improvements and development of \"... 393 more characters,\n",
      "      metadata: {\n",
      "        source: \"https://docs.smith.langchain.com/user_guide\",\n",
      "        loc: { lines: [Object] }\n",
      "      }\n",
      "    }\n",
      "  ]\n",
      "}\n",
      "{ answer: \"\" }\n",
      "{ answer: \"Lang\" }\n",
      "{ answer: \"Smith\" }\n",
      "{ answer: \" offers\" }\n",
      "{ answer: \" a\" }\n",
      "{ answer: \" comprehensive\" }\n",
      "{ answer: \" suite\" }\n",
      "{ answer: \" of\" }\n",
      "{ answer: \" tools\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" workflows\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" support\" }\n",
      "{ answer: \" the\" }\n",
      "{ answer: \" development\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" testing\" }\n",
      "{ answer: \" of\" }\n",
      "{ answer: \" L\" }\n",
      "{ answer: \"LM\" }\n",
      "{ answer: \" applications\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" Here\" }\n",
      "{ answer: \" are\" }\n",
      "{ answer: \" some\" }\n",
      "{ answer: \" key\" }\n",
      "{ answer: \" features\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" functionalities\" }\n",
      "{ answer: \":\\n\\n\" }\n",
      "{ answer: \"1\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Test\" }\n",
      "{ answer: \" Case\" }\n",
      "{ answer: \" Management\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\\n\" }\n",
      "{ answer: \"  \" }\n",
      "{ answer: \" -\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Bulk\" }\n",
      "{ answer: \" Upload\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" Creation\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\" }\n",
      "{ answer: \" You\" }\n",
      "{ answer: \" can\" }\n",
      "{ answer: \" upload\" }\n",
      "{ answer: \" test\" }\n",
      "{ answer: \" cases\" }\n",
      "{ answer: \" in\" }\n",
      "{ answer: \" bulk\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" create\" }\n",
      "{ answer: \" them\" }\n",
      "{ answer: \" on\" }\n",
      "{ answer: \" the\" }\n",
      "{ answer: \" fly\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" or\" }\n",
      "{ answer: \" export\" }\n",
      "{ answer: \" them\" }\n",
      "{ answer: \" from\" }\n",
      "{ answer: \" application\" }\n",
      "{ answer: \" traces\" }\n",
      "{ answer: \".\\n\" }\n",
      "{ answer: \"  \" }\n",
      "{ answer: \" -\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Datas\" }\n",
      "{ answer: \"ets\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\" }\n",
      "{ answer: \" Lang\" }\n",
      "{ answer: \"Smith\" }\n",
      "{ answer: \" allows\" }\n",
      "{ answer: \" you\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" create\" }\n",
      "{ answer: \" datasets\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" which\" }\n",
      "{ answer: \" are\" }\n",
      "{ answer: \" collections\" }\n",
      "{ answer: \" of\" }\n",
      "{ answer: \" inputs\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" reference\" }\n",
      "{ answer: \" outputs\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" These\" }\n",
      "{ answer: \" datasets\" }\n",
      "{ answer: \" can\" }\n",
      "{ answer: \" be\" }\n",
      "{ answer: \" used\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" run\" }\n",
      "{ answer: \" tests\" }\n",
      "{ answer: \" on\" }\n",
      "{ answer: \" your\" }\n",
      "{ answer: \" L\" }\n",
      "{ answer: \"LM\" }\n",
      "{ answer: \" applications\" }\n",
      "{ answer: \".\\n\\n\" }\n",
      "{ answer: \"2\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Custom\" }\n",
      "{ answer: \" Evalu\" }\n",
      "{ answer: \"ations\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\\n\" }\n",
      "{ answer: \"  \" }\n",
      "{ answer: \" -\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"LL\" }\n",
      "{ answer: \"M\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" He\" }\n",
      "{ answer: \"uristic\" }\n",
      "{ answer: \" Based\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\" }\n",
      "{ answer: \" You\" }\n",
      "{ answer: \" can\" }\n",
      "{ answer: \" run\" }\n",
      "{ answer: \" custom\" }\n",
      "{ answer: \" evaluations\" }\n",
      "{ answer: \" using\" }\n",
      "{ answer: \" both\" }\n",
      "{ answer: \" L\" }\n",
      "{ answer: \"LM\" }\n",
      "{ answer: \"-based\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" heuristic\" }\n",
      "{ answer: \"-based\" }\n",
      "{ answer: \" methods\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" score\" }\n",
      "{ answer: \" test\" }\n",
      "{ answer: \" results\" }\n",
      "{ answer: \".\\n\\n\" }\n",
      "{ answer: \"3\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Comparison\" }\n",
      "{ answer: \" View\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\\n\" }\n",
      "{ answer: \"  \" }\n",
      "{ answer: \" -\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Pro\" }\n",
      "{ answer: \"tot\" }\n",
      "{ answer: \"yp\" }\n",
      "{ answer: \"ing\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" Regression\" }\n",
      "{ answer: \" Tracking\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\" }\n",
      "{ answer: \" When\" }\n",
      "{ answer: \" prot\" }\n",
      "{ answer: \"otyping\" }\n",
      "{ answer: \" different\" }\n",
      "{ answer: \" versions\" }\n",
      "{ answer: \" of\" }\n",
      "{ answer: \" your\" }\n",
      "{ answer: \" applications\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" Lang\" }\n",
      "{ answer: \"Smith\" }\n",
      "{ answer: \" provides\" }\n",
      "{ answer: \" a\" }\n",
      "{ answer: \" comparison\" }\n",
      "{ answer: \" view\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" see\" }\n",
      "{ answer: \" if\" }\n",
      "{ answer: \" there\" }\n",
      "{ answer: \" have\" }\n",
      "{ answer: \" been\" }\n",
      "{ answer: \" any\" }\n",
      "{ answer: \" regress\" }\n",
      "{ answer: \"ions\" }\n",
      "{ answer: \" with\" }\n",
      "{ answer: \" respect\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" your\" }\n",
      "{ answer: \" initial\" }\n",
      "{ answer: \" test\" }\n",
      "{ answer: \" cases\" }\n",
      "{ answer: \".\\n\\n\" }\n",
      "{ answer: \"4\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Native\" }\n",
      "{ answer: \" Rendering\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\\n\" }\n",
      "{ answer: \"  \" }\n",
      "{ answer: \" -\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Chat\" }\n",
      "{ answer: \" Messages\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" Functions\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" Documents\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\" }\n",
      "{ answer: \" Lang\" }\n",
      "{ answer: \"Smith\" }\n",
      "{ answer: \" provides\" }\n",
      "{ answer: \" native\" }\n",
      "{ answer: \" rendering\" }\n",
      "{ answer: \" of\" }\n",
      "{ answer: \" chat\" }\n",
      "{ answer: \" messages\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" functions\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" retrieved\" }\n",
      "{ answer: \" documents\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" making\" }\n",
      "{ answer: \" it\" }\n",
      "{ answer: \" easier\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" visualize\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" understand\" }\n",
      "{ answer: \" the\" }\n",
      "{ answer: \" outputs\" }\n",
      "{ answer: \".\\n\\n\" }\n",
      "{ answer: \"5\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Pro\" }\n",
      "{ answer: \"tot\" }\n",
      "{ answer: \"yp\" }\n",
      "{ answer: \"ing\" }\n",
      "{ answer: \" Support\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\\n\" }\n",
      "{ answer: \"  \" }\n",
      "{ answer: \" -\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Quick\" }\n",
      "{ answer: \" Experiment\" }\n",
      "{ answer: \"ation\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\" }\n",
      "{ answer: \" The\" }\n",
      "{ answer: \" platform\" }\n",
      "{ answer: \" supports\" }\n",
      "{ answer: \" quick\" }\n",
      "{ answer: \" experimentation\" }\n",
      "{ answer: \" with\" }\n",
      "{ answer: \" different\" }\n",
      "{ answer: \" prompts\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" model\" }\n",
      "{ answer: \" types\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" retrieval\" }\n",
      "{ answer: \" strategies\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" other\" }\n",
      "{ answer: \" parameters\" }\n",
      "{ answer: \".\\n\\n\" }\n",
      "{ answer: \"6\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Feedback\" }\n",
      "{ answer: \" Capture\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\\n\" }\n",
      "{ answer: \"  \" }\n",
      "{ answer: \" -\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Human\" }\n",
      "{ answer: \" Feedback\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\" }\n",
      "{ answer: \" When\" }\n",
      "{ answer: \" launching\" }\n",
      "{ answer: \" your\" }\n",
      "{ answer: \" application\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" an\" }\n",
      "{ answer: \" initial\" }\n",
      "{ answer: \" set\" }\n",
      "{ answer: \" of\" }\n",
      "{ answer: \" users\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" Lang\" }\n",
      "{ answer: \"Smith\" }\n",
      "{ answer: \" allows\" }\n",
      "{ answer: \" you\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" gather\" }\n",
      "{ answer: \" human\" }\n",
      "{ answer: \" feedback\" }\n",
      "{ answer: \" on\" }\n",
      "{ answer: \" the\" }\n",
      "{ answer: \" responses\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" This\" }\n",
      "{ answer: \" helps\" }\n",
      "{ answer: \" identify\" }\n",
      "{ answer: \" interesting\" }\n",
      "{ answer: \" runs\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" highlight\" }\n",
      "{ answer: \" edge\" }\n",
      "{ answer: \" cases\" }\n",
      "{ answer: \" causing\" }\n",
      "{ answer: \" problematic\" }\n",
      "{ answer: \" responses\" }\n",
      "{ answer: \".\\n\" }\n",
      "{ answer: \"  \" }\n",
      "{ answer: \" -\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Feedback\" }\n",
      "{ answer: \" Scores\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\" }\n",
      "{ answer: \" You\" }\n",
      "{ answer: \" can\" }\n",
      "{ answer: \" attach\" }\n",
      "{ answer: \" feedback\" }\n",
      "{ answer: \" scores\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" logged\" }\n",
      "{ answer: \" traces\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" often\" }\n",
      "{ answer: \" integrated\" }\n",
      "{ answer: \" into\" }\n",
      "{ answer: \" the\" }\n",
      "{ answer: \" system\" }\n",
      "{ answer: \".\\n\\n\" }\n",
      "{ answer: \"7\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Monitoring\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" Troubles\" }\n",
      "{ answer: \"hooting\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\\n\" }\n",
      "{ answer: \"  \" }\n",
      "{ answer: \" -\" }\n",
      "{ answer: \" **\" }\n",
      "{ answer: \"Logging\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" Visualization\" }\n",
      "{ answer: \"**\" }\n",
      "{ answer: \":\" }\n",
      "{ answer: \" Lang\" }\n",
      "{ answer: \"Smith\" }\n",
      "{ answer: \" logs\" }\n",
      "{ answer: \" all\" }\n",
      "{ answer: \" traces\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" visual\" }\n",
      "{ answer: \"izes\" }\n",
      "{ answer: \" latency\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" token\" }\n",
      "{ answer: \" usage\" }\n",
      "{ answer: \" statistics\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" helps\" }\n",
      "{ answer: \" troubleshoot\" }\n",
      "{ answer: \" specific\" }\n",
      "{ answer: \" issues\" }\n",
      "{ answer: \" as\" }\n",
      "{ answer: \" they\" }\n",
      "{ answer: \" arise\" }\n",
      "{ answer: \".\\n\\n\" }\n",
      "{ answer: \"Overall\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" Lang\" }\n",
      "{ answer: \"Smith\" }\n",
      "{ answer: \" is\" }\n",
      "{ answer: \" designed\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" support\" }\n",
      "{ answer: \" the\" }\n",
      "{ answer: \" entire\" }\n",
      "{ answer: \" lifecycle\" }\n",
      "{ answer: \" of\" }\n",
      "{ answer: \" L\" }\n",
      "{ answer: \"LM\" }\n",
      "{ answer: \" application\" }\n",
      "{ answer: \" development\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" from\" }\n",
      "{ answer: \" initial\" }\n",
      "{ answer: \" prot\" }\n",
      "{ answer: \"otyping\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" deployment\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" ongoing\" }\n",
      "{ answer: \" monitoring\" }\n",
      "{ answer: \",\" }\n",
      "{ answer: \" making\" }\n",
      "{ answer: \" it\" }\n",
      "{ answer: \" a\" }\n",
      "{ answer: \" powerful\" }\n",
      "{ answer: \" tool\" }\n",
      "{ answer: \" for\" }\n",
      "{ answer: \" developers\" }\n",
      "{ answer: \" looking\" }\n",
      "{ answer: \" to\" }\n",
      "{ answer: \" build\" }\n",
      "{ answer: \" and\" }\n",
      "{ answer: \" maintain\" }\n",
      "{ answer: \" high\" }\n",
      "{ answer: \"-quality\" }\n",
      "{ answer: \" L\" }\n",
      "{ answer: \"LM\" }\n",
      "{ answer: \" applications\" }\n",
      "{ answer: \".\" }\n",
      "{ answer: \"\" }\n"
     ]
    }
   ],
   "source": [
    "const stream = await conversationalRetrievalChain.stream({\n",
    "  messages: [\n",
    "    new HumanMessage(\"Can LangSmith help test my LLM applications?\"),\n",
    "    new AIMessage(\n",
    "      \"Yes, LangSmith can help test and evaluate your LLM applications. It allows you to quickly edit examples and add them to datasets to expand the surface area of your evaluation sets or to fine-tune a model for improved quality or reduced costs. Additionally, LangSmith can be used to monitor your application, log all traces, visualize latency and token usage statistics, and troubleshoot specific issues as they arise.\"\n",
    "    ),\n",
    "    new HumanMessage(\"Tell me more!\"),\n",
    "  ],\n",
    "});\n",
    "\n",
    "for await (const chunk of stream) {\n",
    "  console.log(chunk);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next steps\n",
    "\n",
    "You've now learned some techniques for adding personal data as context to your chatbots.\n",
    "\n",
    "This guide only scratches the surface of retrieval techniques. For more on different ways of ingesting, preparing, and retrieving the most relevant data, check out our [how to guides on retrieval](/docs/how_to/#retrievers)."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Deno",
   "language": "typescript",
   "name": "deno"
  },
  "language_info": {
   "file_extension": ".ts",
   "mimetype": "text/x.typescript",
   "name": "typescript",
   "nb_converter": "script",
   "pygments_lexer": "typescript",
   "version": "5.3.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
